package model

import (
	"fmt"
	"team-evaluate/pkg/setting"
	"time"

	"gorm.io/driver/mysql"

	_ "gorm.io/driver/mysql"
	"gorm.io/gorm"
)

type Model struct {
	ID         uint32 `gorm:"primaryKey" json:"id"`
	CreatedBy  uint32 `json:"created_by"`
	ModifiedBy uint32 `json:"modified_by"`
	CreatedOn  uint64 `json:"created_on"`
	ModifiedOn uint64 `json:"modified_on"`
	DeletedOn  uint64 `json:"deleted_on"`
	IsDel      uint8  `gorm:"default:0" json:"is_del"`
}

func NewDBEngine(databaseSetting *setting.DatabaseSettingS) (*gorm.DB, error) {
	db, err := gorm.Open(mysql.Open(fmt.Sprintf("%s:%s@tcp(%s:%s)/%s?charset=%s&parseTime=%t&loc=Local",
		databaseSetting.UserName,
		databaseSetting.Password,
		databaseSetting.Host,
		databaseSetting.Port,
		databaseSetting.DBName,
		databaseSetting.Charset,
		databaseSetting.ParseTime,
	)), &gorm.Config{
		PrepareStmt:                              true, //打开预编译模式
		DisableForeignKeyConstraintWhenMigrating: true, // 禁用动创建数据库外键约束
	})
	if err != nil {
		return nil, err
	}

	//自动迁移
	err = db.AutoMigrate(&User{}, &Team{}, &UserTeam{})
	if err != nil {
		return nil, err
	}
	sqlDB, _ := db.DB()
	sqlDB.SetMaxIdleConns(databaseSetting.MaxIdleConns)
	sqlDB.SetMaxOpenConns(databaseSetting.MaxOpenConns)
	// 注册回调
	db.Callback().Create().Before("gorm:create").Register("update_created_at", updateTimeStampForCreateCallback)
	db.Callback().Update().Before("gorm:update").Register("my_plugin:before_update", updateTimeStampForUpdateCallback)
	return db, nil
}

// 新增行为的回调
func updateTimeStampForCreateCallback(db *gorm.DB) {
	if db.Error == nil && db.Statement.Schema != nil {
		nowTime := time.Now().Unix() * 1000 //默认是秒数，前端使用毫秒数
		if createTimeField, ok := db.Statement.Schema.FieldsByName["CreatedOn"]; ok {
			if _, isZero := createTimeField.ValueOf(db.Statement.ReflectValue); isZero {
				_ = createTimeField.Set(db.Statement.ReflectValue, nowTime)
			}
		}
		if modifiedTimeField, ok := db.Statement.Schema.FieldsByName["ModifiedOn"]; ok {
			if _, isZero := modifiedTimeField.ValueOf(db.Statement.ReflectValue); isZero {
				_ = modifiedTimeField.Set(db.Statement.ReflectValue, nowTime)
			}
		}
	}
}

// 更新行为的回调
func updateTimeStampForUpdateCallback(db *gorm.DB) {
	if db.Error == nil && db.Statement.Schema != nil {
		nowTime := time.Now().Unix() * 1000
		db.Statement.SetColumn("ModifiedOn", nowTime, true)
	}
}
